package com.google.code.stalkernet.database;

import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;

import com.google.code.stalkernet.database.event.DatabaseEvent;
import com.google.code.stalkernet.database.event.DatabaseListener;
import com.google.code.stalkernet.entry.Entry;

/**
 * Abstract base class for implementations of {@link Database} interface.
 *
 * @author Mikhail Vladimirov
 */
public abstract class AbstractDatabase implements Database
{
    private final Collection <DatabaseListener> databaseListeners =
        new CopyOnWriteArrayList <> ();

    /**
     * {@inheritDoc}
     */
    @Override
    public void addDatabaseListener (DatabaseListener databaseListener)
    {
        if (databaseListener == null)
            throw new IllegalArgumentException ("Database listener is null");

        databaseListeners.add (databaseListener);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void removeDatabaseListener (DatabaseListener databaseListener)
    {
        if (databaseListener == null)
            throw new IllegalArgumentException ("Database listener is null");

        databaseListeners.remove (databaseListener);
    }

    /**
     * Get all registered database listeners.
     *
     * @return an array of {@link DatabaseListener} objects
     */
    public DatabaseListener [] getAllDatabaseListeners ()
    {
        return databaseListeners.toArray (
            new DatabaseListener [databaseListeners.size ()]);
    }

    /**
     * Notify all registered listeners about new added entry.
     *
     * @param entry new added entry
     */
    protected void fireEntryAdded (Entry entry)
    {
        if (entry == null)
            throw new IllegalArgumentException ("Entry is null");

        DatabaseEvent databaseEvent = null;
        for (DatabaseListener databaseListener: databaseListeners)
        {
            if (databaseEvent == null)
                databaseEvent = new DatabaseEvent (this, entry);

            databaseListener.entryAdded (databaseEvent);
        }
    }
}
